/**
 *  @file  vsFixedSizeFileOutput.h version 1.0 2007-11-20 
 *  @brief Define class FixedSizeFileOutput.
 *  Copyright (c) 2007 by @author <abitfree@gmail.com>
 */

#ifndef __VS_FIXED_SIZE_FILE_OUTPUT_H__
#define __VS_FIXED_SIZE_FILE_OUTPUT_H__

#include "vsFileOutput.h"

namespace vs {
namespace log {


/**
 * @brief The fixed size file log output class.
 *
 * The size of the log file is fixed, if a log output object is running, it may have many fixed size log files.
 */
class FixedSizeFileOutput : public FileOutput
{
public:
	/// The default max size of single log file.
	enum { DEFAULT_MAX_LOGFILE_SIZE = 1024*1024*10 };

	/// The constructor.
	FixedSizeFileOutput(long nMaxSize = DEFAULT_MAX_LOGFILE_SIZE, const char *pszFileHeader = 0, const char *pszDirectory = 0);

	/// The destructor.
	~FixedSizeFileOutput();

	/// Write a log message, it is usually called by the Logger class objects.
	virtual int Write(const char *pszMsg, int nSize, struct tm *pWriteTime);

	/// Set the max size for a single log output object.
	void SetMaxFileSize(long nMaxSize);
	
protected:
	/// Get the file name of the current FileOutput.
	virtual const char* GetFileName();
    
	/// Switch a file, if needed.
	virtual void SwitchFile(int nWriteSize, struct tm *pWriteTime);
	
private:
	// The current number of the log output.
	int m_nCurrNumber;

	// The total bytes of the wrote logging data.
	long m_nWroteBytes;

	// The max bytes of the log output.
	long m_nMaxBytes;
};

#define INLINE inline

INLINE
FixedSizeFileOutput::FixedSizeFileOutput(long nMaxSize, const char *pszFileHeader, const char *pszDirectory)
	: FileOutput(pszFileHeader, pszDirectory), m_nCurrNumber(1), m_nWroteBytes(0), m_nMaxBytes(nMaxSize)
{
}

INLINE
FixedSizeFileOutput::~FixedSizeFileOutput()
{
	Close();
}

INLINE
int FixedSizeFileOutput::Write(const char *pszMsg, int nSize, struct tm *pWriteTime)
{
	SwitchFile(nSize, pWriteTime);
	int size = fwrite(pszMsg, 1, nSize, m_File);
	m_nWroteBytes += size;
	return size;
}

INLINE
const char* FixedSizeFileOutput::GetFileName()
{
    time_t tNow;
	tNow = time(0);
	struct tm *pTm = localtime(&tNow);
	static char file_name[MAX_FILE_NAME];
    _snprintf(file_name, MAX_FILE_NAME, "%s\\%s_%04d%02d%02d%02d%02d%02d%d.log", GetLogDirectory(), GetLogFileNameHeader(), pTm->tm_year+1900, 
                        pTm->tm_mon+1, pTm->tm_mday, pTm->tm_hour, pTm->tm_min, pTm->tm_sec, m_nCurrNumber);
	return file_name;
}

INLINE
void FixedSizeFileOutput::SetMaxFileSize(long nMaxSize)
{
	m_nMaxBytes = nMaxSize;
}

inline
void FixedSizeFileOutput::SwitchFile(int nWriteSize, struct tm *pWriteTime)
{
	if (m_nWroteBytes + nWriteSize > m_nMaxBytes)
	{
		m_nWroteBytes = 0;
		++m_nCurrNumber;
        
		// will close log file in Open().
		Open();
	}
}

} // namespace log
} // namespace vs

#endif // __VS_FIXED_SIZE_FILE_OUTPUT_H__
